
package com.gitee.jmash.storage.service;

import com.gitee.jmash.common.lock.DistributedLock;
import com.gitee.jmash.common.utils.UUIDUtil;
import com.gitee.jmash.core.jaxrs.ParamsValidationException;
import com.gitee.jmash.core.orm.cdi.JpaTenantService;
import com.gitee.jmash.core.transaction.JakartaTransaction;
import com.gitee.jmash.core.utils.FieldMaskUtil;
import com.gitee.jmash.storage.entity.StorageOrganInfoEntity;
import com.gitee.jmash.storage.mapper.StorageOrganInfoMapper;
import jakarta.enterprise.inject.Typed;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import jakarta.transaction.Transactional.TxType;
import jakarta.validation.ValidationException;
import jakarta.validation.executable.ValidateOnExecution;
import java.util.Set;
import java.util.UUID;
import jmash.storage.protobuf.StorageOrganInfoCreateReq;
import jmash.storage.protobuf.StorageOrganInfoEnableKey;
import jmash.storage.protobuf.StorageOrganInfoUpdateReq;
import jmash.storage.protobuf.StorageOrganKey;
import jmash.storage.protobuf.StorageOrganUserCreateReq;
import org.apache.commons.lang3.StringUtils;

/**
 * storage_organ_info写服务.
 *
 * @author <a href="mailto:service@crenjoy.com">crenjoy</a>
 */
@Typed(StorageOrganInfoWrite.class)
@Transactional(TxType.REQUIRED)
@JpaTenantService
@ValidateOnExecution
public class StorageOrganInfoWriteBean extends StorageOrganInfoReadBean
    implements StorageOrganInfoWrite, JakartaTransaction {

  @Inject
  DistributedLock lock;

  @Inject
  StorageOrganUserWrite userWrite;

  @Override
  @PersistenceContext(unitName = "WriteStorage")
  public void setEntityManager(EntityManager entityManager) {
    this.tem.setEntityManager(entityManager, true);
  }

  @Override
  public StorageOrganInfoEntity insert(StorageOrganInfoCreateReq req) {
    UUID organId = UUIDUtil.fromString(req.getOrganId());
    // 1.业务校验.
    StorageOrganInfoEntity entity = storageOrganInfoDao
        .findOrganService(organId, req.getServiceType());
    if (entity != null) {
      throw new ParamsValidationException("organId", "组织已开通该服务！");
    }
    entity = StorageOrganInfoMapper.INSTANCE.create(req);
    // 2.仅校验,不执行.
    if (req.getValidateOnly()) {
      return entity;
    }
    // 3.检查是否重复请求.
    if (!lock.lock(req.getRequestId(), 60)) {
      throw new ParamsValidationException("requestId", "客户端发起重复请求");
    }
    // 4.执行业务(创建人及时间内部处理.)
    storageOrganInfoDao.persist(entity);
    if (StringUtils.isNotBlank(req.getUnifiedId())) {
      StorageOrganUserCreateReq.Builder userReq = StorageOrganUserCreateReq.newBuilder();
      userReq.setTenant(req.getTenant()).setRequestId(UUID.randomUUID().toString());
      userReq.setOrganId(req.getOrganId()).setUnifiedId(req.getUnifiedId())
          .setIsDefault(req.getIsDefault());
      userWrite.addOrganUser(userReq.build());
    }
    return entity;
  }


  @Override
  public boolean enable(StorageOrganInfoEnableKey storageOrganInfoEnableKey) {


    return false;
  }

  @Override
  public StorageOrganInfoEntity delete(UUID entityId) {
    StorageOrganInfoEntity entity = storageOrganInfoDao.removeById(entityId);
    return entity;
  }

  @Override
  public int deleteByIdAndType(StorageOrganKey req) {
    return storageOrganInfoDao.deleteByIdAndType(req.getOrganId(), req.getServiceType());
  }

  @Override
  public Integer batchDelete(Set<UUID> entityIds) {
    int i = 0;
    for (UUID entityId : entityIds) {
      storageOrganInfoDao.removeById(entityId);
      i++;
    }
    return i;
  }

  @Override
  public StorageOrganInfoEntity update(StorageOrganInfoUpdateReq req) {
    UUID organId = UUIDUtil.fromString(req.getOrganId());
    // 1.业务校验.
    StorageOrganInfoEntity entity = storageOrganInfoDao
        .findOrganService(organId, req.getServiceType());
    if (null == entity) {
      throw new ValidationException("找不到实体:" + req.getOrganId());
    }
    // 无需更新,返回当前数据库数据.
    if (req.getUpdateMask().getPathsCount() == 0) {
      return entity;
    }
    // 更新掩码属性
    FieldMaskUtil.copyMask(entity, req, req.getUpdateMask());
    // 1.业务校验.
    // 2.仅校验,不执行.
    if (req.getValidateOnly()) {
      return entity;
    }
    // 3.检查是否重复请求.
    if (!lock.lock(req.getRequestId(), 60)) {
      throw new ParamsValidationException("requestId", "客户端发起重复请求");
    }
    // 4.执行业务
    storageOrganInfoDao.merge(entity);
    return entity;
  }

}
